package cn.com.common.job.task;

import java.math.BigDecimal;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.Duration;
import java.time.Instant;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import org.quartz.DisallowConcurrentExecution;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;

import cn.com.common.constants.Constants;
import cn.com.gas.entity.GasCaminfoForecastEntity;
import cn.com.gas.entity.GasOfflineCamEntity;
import cn.com.gas.entity.GasServerAreaEntity;
import cn.com.gas.entity.GasServerChannelEntity;
import cn.com.gas.entity.GasStationinfoEntity;
import cn.com.gas.entity.GasStationinfoForecastMonthEntity;
import cn.com.gas.entity.GasStaytimeResultEntity;
import cn.com.gas.service.GasOfflineCamService;
import cn.com.gas.service.GasServerAreaService;
import cn.com.gas.service.GasServerChannelService;
import cn.com.gas.service.GasStationinfoForecastMonthService;
import cn.com.gas.service.GasStationinfoService;
import cn.com.gas.service.GasStaytimeResultService;
import cn.com.util.TsBqUtils;

/**
 * 未使用 此定时任务
 * @author shaochangyang
 *
 */
@Component("gasStationMonthForecastProcessTask")
@DisallowConcurrentExecution
public class GasStationMonthForecastProcessTask {
	// 未使用
	@Value("${gasstation.timedTask.gasStationMonthForecastProcessTask}")
	private String gasStationMonthForecastProcessTask;
	
	private Logger logger = LoggerFactory.getLogger(getClass());

	
	
	@Autowired
	private GasStationinfoService stationinfoService;
	@Autowired
	private GasStaytimeResultService staytimeResultService;
	@Autowired
	private GasStationinfoForecastMonthService gasStationinfoForecastMonthService;
	@Autowired
	private GasServerAreaService serverAreaService;
	@Autowired
	private GasServerChannelService serverChannelService;
	@Autowired
	private GasOfflineCamService offlineCamService;

	public void run(String params) throws Exception {
		logger.debug("gasStationMonthForecastProcessTask定时任务正在执行，参数为：{}", params);

		logger.debug("application参数为gasStationMonthForecastProcessTask：{}", gasStationMonthForecastProcessTask);

		if (gasStationMonthForecastProcessTask.equals(Constants.JOB_STOP)) {


			logger.debug("application配置文件控制不执行gasStationMonthForecastProcessTask定时任务");
			throw new Exception("application配置文件控制不执行gasStationMonthForecastProcessTask定时任务");
		
		
		}
		
		
		Date date = new Date();
		SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		DateTimeFormatter _formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");

		// 获取上个月第一天
		LocalDate firstDayOfLastMonth = LocalDate.now().minusMonths(1).withDayOfMonth(1);
		// 获取上个月最后一天
		LocalDate lastDayOfLastMonth = LocalDate.now().minusMonths(1)
				.withDayOfMonth(LocalDate.now().minusMonths(1).lengthOfMonth());
		logger.debug("上个月第一天：" + firstDayOfLastMonth);
		logger.debug("上个月最后一天：" + lastDayOfLastMonth);

		Calendar calendar = Calendar.getInstance();
		// 将当前日期回退一个月
		calendar.add(Calendar.MONTH, -1);
		// 获取上个月的最大日数
		int maxDayOfPreviousMonth = calendar.getActualMaximum(Calendar.DAY_OF_MONTH);
		logger.debug("上个月的天数是: " + maxDayOfPreviousMonth);

		LocalDate yesterday = LocalDate.now().minusDays(1);
		
		LocalDateTime startOfYesterday = LocalDateTime.of(yesterday, LocalTime.MIN);
		LocalDateTime endOfYesterday = LocalDateTime.of(yesterday, LocalTime.MAX);

		// 计算离线率  上个月的
		LambdaQueryWrapper<GasOfflineCamEntity> queryOfflineCam = Wrappers.lambdaQuery();
		
		queryOfflineCam.ge(GasOfflineCamEntity::getCreateTime, firstDayOfLastMonth);
		queryOfflineCam.le(GasOfflineCamEntity::getCreateTime, lastDayOfLastMonth);
		queryOfflineCam.isNotNull(GasOfflineCamEntity::getOfflineTime);
		
		List<GasOfflineCamEntity> offlineCamList = offlineCamService.list(queryOfflineCam);
		
		List<GasOfflineCamEntity> TimePeriodList = new ArrayList<GasOfflineCamEntity>();

		for (GasOfflineCamEntity offlineCam : offlineCamList) {

			String offlineTime = offlineCam.getOfflineTime();
			String offlineTimeHandle = offlineTime.substring(0, 10);
			
			String recoverTime = offlineCam.getRecoverTime();
			try {
				Date offlineTimeDate = formatter.parse(offlineTime);

				if (TsBqUtils.isNull(recoverTime)) {
					recoverTime = offlineTimeHandle + " 23:59:59";
				} else {
					Date recoverTimeDate = formatter.parse(recoverTime);
					if (endOfYesterday.isBefore(dateToLocalDateTime(recoverTimeDate))) {
						recoverTime = offlineTimeHandle + " 23:59:59";
					}
				}

				if (dateToLocalDateTime(offlineTimeDate).isBefore(startOfYesterday)) {
					offlineTime = offlineTimeHandle + " 00:00:01";
				}

				Duration duration = Duration.between(dateToLocalDateTime(formatter.parse(offlineTime)),
						dateToLocalDateTime(formatter.parse(recoverTime)));

				long minutes = duration.toMillis() / 1000; // 相差秒数

				offlineCam.setTimePeriod(String.valueOf(minutes));
				TimePeriodList.add(offlineCam);

			} catch (ParseException e) {
				logger.error(e.getMessage() + "====offlineCam====" + offlineCam.getId());
				e.printStackTrace();
			}

		}
		

		List<GasOfflineCamEntity> offlineCamGroup = new ArrayList<GasOfflineCamEntity>();
		if (TsBqUtils.isNotNull(TimePeriodList)) {

			Map<String, List<GasOfflineCamEntity>> groupedItems = TimePeriodList.stream()
					.collect(Collectors.groupingBy(item -> item.getCamId()));
			groupedItems.forEach((category, itemsInCategory) -> {
				if (TsBqUtils.isNotNull(category)) {
					BigDecimal[] timePeriod = { new BigDecimal(0) };
					itemsInCategory.forEach(item -> {
						timePeriod[0] = timePeriod[0].add(new BigDecimal(item.getTimePeriod()));
					});

					GasOfflineCamEntity offlineCam = new GasOfflineCamEntity();
					offlineCam.setCamId(category);

					offlineCam.setTimePeriod(timePeriod[0].toString());

					offlineCamGroup.add(offlineCam);

				}
			});
		}

		// 计算时间情况
		LambdaQueryWrapper<GasStaytimeResultEntity> queryStaytimeResult = Wrappers.lambdaQuery();
		
		Date firstDayOfLastMonthDate = Date.from(firstDayOfLastMonth.atStartOfDay(ZoneId.systemDefault()).toInstant());
		Date lastDayOfLastMonthDate = Date.from(lastDayOfLastMonth.atStartOfDay(ZoneId.systemDefault()).toInstant());

		queryStaytimeResult.ge(GasStaytimeResultEntity::getMessageDisappear, firstDayOfLastMonthDate);
		queryStaytimeResult.le(GasStaytimeResultEntity::getMessageDisappear, lastDayOfLastMonthDate);
		
		List<GasStaytimeResultEntity> staytimeResultList = staytimeResultService.list(queryStaytimeResult);

		List<GasStaytimeResultEntity> camidAndPriceList = new ArrayList<>();

		for (GasStaytimeResultEntity staytimeResult : staytimeResultList) {

			String camid = staytimeResult.getField5();
			String price = staytimeResult.getPrice();

			if (TsBqUtils.isNull(camid)) {
				// 如果camid 为null 特殊方式获取

				String messageChannel = staytimeResult.getMessageChannel();
				String fromTopic = staytimeResult.getFromTopic();
				String messageAreanumber = staytimeResult.getMessageAreanumber();

				LambdaQueryWrapper<GasServerChannelEntity> serverChannelQueryWrapper = Wrappers.lambdaQuery();

				serverChannelQueryWrapper.eq(GasServerChannelEntity::getTopic, fromTopic);

				List<GasServerChannelEntity> gasServerChannelList = serverChannelService
						.list(serverChannelQueryWrapper);

				if (TsBqUtils.isNotNull(gasServerChannelList)) {

					GasServerChannelEntity serverChannel = gasServerChannelList.get(0);
					String gasServerId = serverChannel.getId();

					LambdaQueryWrapper<GasServerAreaEntity> serverAreaQueryWrapper = Wrappers.lambdaQuery();

					serverAreaQueryWrapper.eq(GasServerAreaEntity::getServerChannel, messageChannel);
					serverAreaQueryWrapper.eq(GasServerAreaEntity::getAreaNumber, messageAreanumber);
					serverAreaQueryWrapper.eq(GasServerAreaEntity::getServerId, gasServerId);

					List<GasServerAreaEntity> serverAreaList = serverAreaService.list(serverAreaQueryWrapper);

					if (TsBqUtils.isNotNull(serverAreaList)) {
						GasServerAreaEntity gasServerAreaEntity = serverAreaList.get(0);
						camid = gasServerAreaEntity.getCamid();
					} else {
					}
				} else {
				}
			}

			if (TsBqUtils.isNotNull(camid)) {

				GasStaytimeResultEntity gasStaytimeResultEntity = new GasStaytimeResultEntity();
				gasStaytimeResultEntity.setPrice(price);
				gasStaytimeResultEntity.setField5(camid);

				camidAndPriceList.add(gasStaytimeResultEntity);
			}
		}

		
		List<GasStaytimeResultEntity> priceCamGroup = new ArrayList<GasStaytimeResultEntity>();

		if (TsBqUtils.isNotNull(camidAndPriceList)) {

			Map<String, List<GasStaytimeResultEntity>> groupedItems = camidAndPriceList.stream()
					.collect(Collectors.groupingBy(item -> item.getField5()));

			groupedItems.forEach((category, itemsInCategory) -> {
				if (TsBqUtils.isNotNull(category)) {
					BigDecimal[] price = { new BigDecimal(0) };
					itemsInCategory.forEach(item -> {
						price[0] = price[0].add(new BigDecimal(item.getPrice()));
					});

					GasStaytimeResultEntity staytimeResult = new GasStaytimeResultEntity();
					staytimeResult.setField5(category);
					staytimeResult.setPrice(price[0].toString());
					priceCamGroup.add(staytimeResult);
				}
			});
		}

		List<GasCaminfoForecastEntity> caminfoForecastList = new ArrayList<>();

		if (TsBqUtils.isNotNull(priceCamGroup)) {

			for (GasStaytimeResultEntity priceCam : priceCamGroup) {
				String price = priceCam.getPrice();
				String field5 = priceCam.getField5();
				
				String timePeriod = "0";
				for (GasOfflineCamEntity offlineCam : offlineCamGroup) {
					String camId = offlineCam.getCamId();
					if (field5.equals(camId)) {
						timePeriod = offlineCam.getTimePeriod();
					}
				}

				GasCaminfoForecastEntity caminfoForecast = new GasCaminfoForecastEntity();
				GasStationinfoEntity gasStationinfo = stationinfoService.getById(field5);
				if (TsBqUtils.isNotNull(gasStationinfo)) {

					caminfoForecast.setTime(startOfYesterday.format(_formatter));
					caminfoForecast.setStationinfoId(gasStationinfo.getPid());
					caminfoForecast.setCamId(gasStationinfo.getId());
					// caminfoForecast.setTaxorgcode();

					caminfoForecast.setGatherValue(price);
					BigDecimal _price = new BigDecimal(price);

					if (TsBqUtils.isNull(timePeriod) || "0".equals(timePeriod)) {
						caminfoForecast.setForecastValue(price);
					} else {
						// TODO
						BigDecimal bigDecimal = new BigDecimal("86400");
						bigDecimal = bigDecimal.multiply(new BigDecimal(maxDayOfPreviousMonth));
						
						BigDecimal divide = _price.multiply(bigDecimal);

						BigDecimal subtract = bigDecimal.subtract(new BigDecimal(timePeriod));

						BigDecimal multiply = divide.divide(subtract, 2, BigDecimal.ROUND_HALF_UP);

						caminfoForecast.setForecastValue(multiply.toString());
						
					}

					caminfoForecast.setOfflineTime(timePeriod);
					caminfoForecast.setDeleted(Constants.DELETEED_NOT);
					caminfoForecast.setCreateId("job");
					caminfoForecast.setCreateTime(date);
					caminfoForecastList.add(caminfoForecast);

				} else {
					logger.debug("gasStationAndCamForecastProcessTask定时任务正在执行，gasStationinfo未查询到camid:" + field5);
				}

			}
		}

		// 保存到 gas_caminfo_forecast
		if (TsBqUtils.isNotNull(caminfoForecastList)) {
			// 先不保存
			/*for (GasCaminfoForecastEntity caminfoForecast : caminfoForecastList) {
				caminfoForecastService.save(caminfoForecast);

			}*/

			List<GasStationinfoForecastMonthEntity> stationinfoForecastList = new ArrayList<>();

			// 保存到 gas_stationinfo_forecast
			Map<String, List<GasCaminfoForecastEntity>> groupedItems = caminfoForecastList.stream()
					.collect(Collectors.groupingBy(item -> item.getStationinfoId()));

			groupedItems.forEach((category, itemsInCategory) -> {
				if (TsBqUtils.isNotNull(category)) {
					BigDecimal[] forecastValue = { new BigDecimal(0) };
					BigDecimal[] gatherValue = { new BigDecimal(0) };

					itemsInCategory.forEach(item -> {
						forecastValue[0] = forecastValue[0].add(new BigDecimal(item.getForecastValue())); // 预估值
						gatherValue[0] = gatherValue[0].add(new BigDecimal(item.getGatherValue())); // 采集值

					});

					GasStationinfoForecastMonthEntity stationinfoForecast = new GasStationinfoForecastMonthEntity();
					GasStationinfoEntity stationinfo = stationinfoService.getById(category);

					stationinfoForecast.setTime(startOfYesterday.format(_formatter));
					stationinfoForecast.setStationinfoId(category);
					stationinfoForecast.setTaxorgcode(stationinfo.getTaxorgcode());

					stationinfoForecast.setGatherValue(gatherValue[0].toString());
					stationinfoForecast.setForecastValue(forecastValue[0].toString());
					stationinfoForecast.setDeleted(Constants.DELETEED_NOT);
					stationinfoForecast.setCreateId("job");
					stationinfoForecast.setCreateTime(date);

					stationinfoForecastList.add(stationinfoForecast);

				}
			});

			if (TsBqUtils.isNotNull(stationinfoForecastList)) {

				for (GasStationinfoForecastMonthEntity stationinfoForecast : stationinfoForecastList) {
					// TODO 数据补偿，没有值的加油站，计算平均作为补偿
					
					String forecastValue = stationinfoForecast.getForecastValue();
					
					String stationinfoId = stationinfoForecast.getStationinfoId();
					GasStationinfoEntity stationinfo = stationinfoService.getById(stationinfoId);
					
					String gasCoverage = stationinfo.getGasCoverage();
					String gasLocation = stationinfo.getGasLocation();

					BigDecimal _forecastValue = new BigDecimal(forecastValue);

					if (TsBqUtils.isNotNull(gasCoverage) && TsBqUtils.isNotNull(gasLocation) && !"0".equals(gasCoverage)
							&& !"0".equals(gasLocation)) {

						BigDecimal divide = _forecastValue.divide(new BigDecimal(gasCoverage), 2,
								BigDecimal.ROUND_HALF_UP);
						_forecastValue = divide.multiply(new BigDecimal(gasLocation));

					}

					stationinfoForecast.setForecastValue(_forecastValue.toString());
					
					gasStationinfoForecastMonthService.save(stationinfoForecast);
					
				}
			}

		}

	}

	private static LocalDateTime dateToLocalDateTime(Date date) {
		Instant instant = date.toInstant();
		return LocalDateTime.ofInstant(instant, ZoneId.systemDefault());

	}

	public static void main(String[] args) throws ParseException {
		// 7382 2024-07-11 23:59:59.523 2024-07-11 21:56:57.409
		// 20 2024-07-11 20:11:45.523 2024-07-11 20:11:25.521
		// 45 2024-07-11 20:14:35.542 2024-07-11 20:13:50.537
		// 50 2024-07-11 19:08:45.118 2024-07-11 19:07:55.112

		// Date date = new Date();
		SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		DateTimeFormatter _formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
		Date date1 = formatter.parse("2024-07-11 20:37:51.824");
		Date date2 = formatter.parse("2024-07-11 00:01:20.512");

		Duration duration = Duration.between(dateToLocalDateTime(date2), dateToLocalDateTime(date1));

		long minutes = duration.toMinutes(); // 相差的分钟数
		System.out.println(minutes);

		LocalDate yesterday = LocalDate.now().minusDays(1);
		LocalDateTime startOfYesterday = LocalDateTime.of(yesterday, LocalTime.MIN);
		LocalDateTime endOfYesterday = LocalDateTime.of(yesterday, LocalTime.MAX);
		String format = startOfYesterday.format(_formatter);

		System.out.println(startOfYesterday);

		System.out.println(format + " 23:59:59");

		System.out.println(dateToLocalDateTime(date2).isBefore(endOfYesterday));
		
		String str = "2024-07-25 20:11:36.979";
		String substring = str.substring(0, 10);
		System.out.println(substring);
		
		
		BigDecimal bigDecimal = new BigDecimal("86400");
		BigDecimal subtract = bigDecimal.multiply(new BigDecimal("30"));
		
		System.out.println(subtract.toString());

	}

}
